<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

use AliyunMNS\Client;
use AliyunMNS\Requests\SendMessageRequest;
use AliyunMNS\Requests\CreateQueueRequest;
use AliyunMNS\Exception\MnsException;

use App\Models\DedustingDevice;
use App\Models\DedustingDevicePoint;
use App\Models\DedustingAlarm;
use App\Models\DedustingAlarmLog;
use Illuminate\Support\Arr;

class Dedusting extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'dedusting';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command. 
     *
     * @return mixed
     */
    public function handle()
    {
        $client = new Client('http://1960429774320704.mns.cn-shanghai.aliyuncs.com', 'LTAIXidsHeo1vYeo', 'vO9c9Yqyha6PNAkFyb4jAQPfJ5rvbU');

        $queueName = 'aliyun-iot-a1msndyoxCw';
        $queue = $client->getQueueRef($queueName);
        
        while (true) {
            // echo "time = ".date("H:i:s")."\n";
            $receiptHandle = NULL;
            try
            {
                $res = $queue->receiveMessage(30);
                $receiptHandle = $res->getReceiptHandle();
                $msg = json_decode($res->getMessageBody());
// var_dump($msg);
                $this->deleteMsg($queue, $receiptHandle);   //拿到消息后删除
// var_dump(json_decode(base64_decode($msg->payload)));
                if ($msg->messagetype == 'upload') {
                    $data = json_decode(base64_decode($msg->payload), true);
                    $this->dealData($data);
                }
            }
            catch (MnsException $e)
            {
                echo "ReceiveMessage Failed: " . $e . "\n";
                return;
            }
            // sleep(5);
        }
        return;
    }

    protected function dealData($data){
        $queryArr = [];
        $insertArr = [];
        try {
            foreach ($data as $one) {
                if (isset($one['vbox']) && isset($one['pressure'])) {
                    $queryArr[] = $one['vbox'];
                    $createdTime = strtotime($one['date']);

                    $field = ['pressure', 'temperature', 'flow', 'concentration', 'input_dew_point', 'ozone_output', 'oxygen_leakage', 'ozone_leakage'];

                    $insertData = array_intersect_key($one, array_flip($field));

                    $insertData['time'] = $createdTime;
                    $insertArr[$one['vbox']] = $insertData;
                }
            }

            if ($queryArr && $insertArr) {
                // $devices = DedustingDevice::whereIn('machine_code', $queryArr)->get()->keyBy('machine_code')->toArray();
                $devices = DedustingDevice::whereIn('machine_code', $queryArr)->pluck('id', 'machine_code')->toArray();

                foreach ($devices as $oneCode => $oneId) {
                    //入缓存
                    $redisDataKey = DedustingDevice::DATA_CACHE_KEY.$oneId;
                    $redisData = json_encode($insertArr[$oneCode]);
                    Redis::set($redisDataKey, $redisData);

                    //报警处理
                    $this->dealAlarm($oneId, $insertArr[$oneCode]);
                }
            }
        } catch (Exception $e) {
            error_log(date("Y-m-d H:i:s")." ReceiveMessage Failed: " . $e->getMessage() ."\n",3,'/tmp/dedusting.log');
        }
    }

    protected function deleteMsg($queue, $receiptHandle){
        try {
            $res = $queue->deleteMessage($receiptHandle);
        } catch (MnsException $e) {
            error_log(date("Y-m-d H:i:s")." DeleteMessage Failed: " . $e."\n",3,'/tmp/dedusting.log');
        }
    }

    protected function dealAlarm($id, $data)
    {
        foreach ($data as $onePointKey => $onePointVal) {
            $settings = DedustingAlarm::getCache($id, $onePointKey);
            if ($settings) {
                foreach ($settings as $cond => $preset) {
                    $settintData = json_decode($preset, true);
                    $res = DedustingAlarmLog::judge($cond, $onePointVal, $settintData['alarm_value']);
                    if ($res) {
                        $settintData['real_value'] = round($onePointVal,3);
                        //报警入缓存 to do
                        //查询是否存在未处理的报警
                        $exists = DedustingAlarmLog::where('device_id', $settintData['device_id'])->where('point', $settintData['point'])->where('alarm_id', $settintData['alarm_id'])->where('status', DedustingAlarmLog::STATUS_NO)->exists();
                        //没有未处理的报警入库 
                        if (!$exists) {
                            DedustingAlarmLog::create($settintData);
                        }
                        
                        //消息推送
                        break;
                    }
                }
            }
        }
    }
}
